<template>
    <div class="container">
        <el-row :gutter="5">
            <!--左树右表-->
            <el-col :span="4">
                <el-card shadow="never">
                    <div slot="header">
                        <el-form :inline="true" size="small">
                            <el-form-item class="el-search-item">
                                <el-input placeholder="输入关键字进行过滤" prefix-icon="el-icon-search" v-model="filterText"></el-input>
                            </el-form-item>
                        </el-form>
                    </div>
                    <div class="tree-dept">
                        <el-tree :data="treeData" :props="treeProps" :expand-on-click-node="false"  node-key="id" @node-click="searchHandleNodeClick"
                                 :filter-node-method="filterNode" ref="searchTreeRef" default-expand-all empty-text="加载中，请稍后..."></el-tree>
                    </div>
                </el-card>
            </el-col>
            <el-col :span="20">
                <el-card shadow="never">
                    <div slot="header">
                        <el-form :inline="true" :model="searchForm" size="small">
                            <el-form-item label="用户名称" class="el-search-item">
                                <el-input v-model="searchForm.accountName" placeholder="请输入用户名检索" clearable></el-input>
                            </el-form-item>
                            <el-form-item label="状态" class="el-search-item">
                                <el-select v-model="searchForm.isEnabled" clearable placeholder="用户状态">
                                    <el-option label="正常" value="1"></el-option>
                                    <el-option label="停用" value="0"></el-option>
                                </el-select>
                            </el-form-item>
                            <el-form-item class="el-search-item">
                                <el-button type="success" plain icon="el-icon-search" @click="getDataList()">查询</el-button>
                            </el-form-item>
                            <el-form-item class="el-search-item">
                                <el-button v-if='hasPerm("sys:user:add")' type="primary" plain icon="el-icon-plus" @click="openAdd">新增</el-button>
                            </el-form-item>
                            <el-form-item class="el-search-item">
                                <el-button v-if='hasPerm("sys:user:import")' type="info" plain icon="el-icon-upload2" @click="handleImport">导入</el-button>
                            </el-form-item>
                            <el-form-item class="el-search-item">
                                <el-button v-if='hasPerm("sys:user:export")' type="danger" plain icon="el-icon-download" @click="openExport">导出</el-button>
                            </el-form-item>
							<el-form-item class="el-search-item">
							    <el-button v-if='hasPerm("sys:user:assign")' type="danger" plain @click="openClearCache">清除所有用户登录权限缓存</el-button>
							</el-form-item>
                        </el-form>
                    </div>
                    <div class="text item">
                        <el-table :data="tableData" :height="tableHeight" style="width: 100%">
                            <el-table-column type="index" label="序号" align="center" width="80"></el-table-column>
                            <el-table-column prop="username" label="账号" align="center" width="80"></el-table-column>
                            <el-table-column prop="accountName" label="用户名" align="center" width="80"></el-table-column>
                            <el-table-column prop="email" label="邮箱" align="center"></el-table-column>
                            <el-table-column prop="deptName" label="所在部门" align="center"></el-table-column>
                            <el-table-column prop="enabled" label="状态" align="center" width="80">
                                <template slot-scope="scope">
                                    <el-switch
                                        v-model="scope.row.enabled"
                                        :active-value="true"
                                        :inactive-value="false"
                                        @change="handleStatusChange(scope.row)"
                                    ></el-switch>
                                </template>
                            </el-table-column>
                            <el-table-column prop="createTime" label="创建时间" align="center"></el-table-column>
                            <el-table-column v-if='hasPerm("sys:user:update") || hasPerm("sys:user:assign") || hasPerm("sys:user:del")' label="更多操作" align="center" width="270">
                                <template slot-scope="scope11">
									<el-button v-if='hasPerm("sys:user:update")' @click="openUpdatePWD(scope11.row)" size="mini" type="text" icon="el-icon-edit">修改密码</el-button>
                                    <el-button v-if='hasPerm("sys:user:update")' @click="openUpdate(scope11.row)" size="mini" type="text" icon="el-icon-edit">编辑</el-button>
                                    <el-button v-if='hasPerm("sys:user:assign")' @click="assignRole(scope11.row)" size="mini" type="text" icon="el-icon-unlock">分配角色</el-button>
                                    <el-button v-if='hasPerm("sys:user:del")' @click="deleteFun(scope11.row)" size="mini" type="text" icon="el-icon-delete">删除</el-button>
                                </template>
                            </el-table-column>
                        </el-table>
                        <!--分页组件-->
                        <el-pagination style="padding: 20px 0 0 0;text-align: center;" background @size-change="handleSizeChange" @current-change="handleCurrentChange"
                            :current-page="pageNum" :page-sizes="[8, 15, 20]" :page-size="pageSize" layout="total, sizes, prev, pager, next, jumper" :total="total">
                        </el-pagination>
                    </div>
                </el-card>

                <!--新增对话框-->
                <el-drawer :title="dialog.dialogTitle" :visible.sync="dialog.visible" :direction="dialog.direction" :size="size" :before-close="handleClose">
                    <el-row class="drawer-table">
                        <el-col :span="24">
                            <el-form :rules="rules" ref="userForm" :model="userForm" size="small" label-width="80px">
                                <el-form-item prop="deptName" label="所属部门">
                                    <el-input @click.native="showAssignDialog(userForm.deptId)" v-model="userForm.deptName" placeholder="请选择所属部门" auto-complete="off"></el-input>
                                </el-form-item>
                                <el-form-item prop="accountName" label="用户姓名">
                                    <el-input v-model="userForm.accountName" placeholder="请输入用户姓名" auto-complete="off"></el-input>
                                </el-form-item>
                                <el-form-item prop="username" label="登录账号">
                                    <el-input v-model="userForm.username" placeholder="请输入登录账号" auto-complete="off"></el-input>
                                </el-form-item>
                                <el-form-item prop="password" label="登录密码" v-if="dialog.flag === 0">
                                    <el-input type="password" v-model="userForm.password" placeholder="请输入登录密码" auto-complete="off"></el-input>
                                </el-form-item>
                                <el-form-item prop="email" label="电子邮箱">
                                    <el-input v-model="userForm.email" placeholder="请输入电子邮箱" auto-complete="off"></el-input>
                                </el-form-item>
                                <el-form-item prop="enabled" label="是否可用">
                                    <el-switch
                                        v-model="userForm.enabled"
                                        active-color="#13ce66"
                                        inactive-color="#ff4949"
                                        active-text="是否可用">
                                    </el-switch>
                                </el-form-item>
                                <el-form-item prop="roleId" label="所属角色">
                                    <el-radio-group v-model="userForm.roleId">
                                        <el-row :gutter="5">
                                            <el-col :span="9" v-for="item in rolesData" :key="item.id">
                                                <el-radio :label="item.id" style="margin-bottom: 10px">{{item.name}}</el-radio>
                                            </el-col>
                                        </el-row>
                                    </el-radio-group>
                                </el-form-item>
                            </el-form>
                        </el-col>
                    </el-row>
                    <el-row class="drawer-footer">
                        <el-col :span="24">
                            <el-button @click="dialog.visible = false" size="small">取 消</el-button>
                            <el-button type="primary" @click="submitFun()" :loading="loading.status" size="small">{{loading.status ? loading.SubText : loading.BtnText}}</el-button>
                        </el-col>
                    </el-row>
                </el-drawer>

				<!--修改密码对话框 -->
                <el-drawer :title="dialogPWD.dialogTitle" :visible.sync="dialogPWD.visible" :direction="dialogPWD.direction" :size="size" :before-close="handleClose">
                    <el-row class="drawer-table">
                        <el-col :span="24">
                            <el-form :rules="rules" ref="userForm" :model="userForm" size="small" label-width="80px">
                                <el-form-item label="新密码">
                                    <el-input v-model="userForm.newPassword" placeholder="请输入密码" auto-complete="off"></el-input>
                                </el-form-item>
                            </el-form>
                        </el-col>
                    </el-row>
                    <el-row class="drawer-footer">
                        <el-col :span="24">
                            <el-button @click="dialogPWD.visible = false" size="small">取 消</el-button>
                            <el-button type="primary" @click="submitFunPWD()" :loading="loading.status" size="small">{{loading.status ? loading.SubText : loading.BtnText}}</el-button>
                        </el-col>
                    </el-row>
                </el-drawer>
				
                <!--上级部门弹框-->
                <el-dialog title="选择部门" :visible.sync="parentDialogVisible" width="25%" top="5%">
                    <el-tree :data="treeData"
                             :props="treeProps"
                             show-checkbox
                             check-strictly
                             node-key="id"
                             default-expand-all
                             :expand-on-click-node="false"
                             :default-checked-keys="defKeys"
                             ref="treeRef"
                             @check-change="handleNodeClick"
                             empty-text="加载中，请稍后..."
                             style="height: 55vh;overflow: auto;"
                    ></el-tree>
                    <span slot="footer" class="dialog-footer">
                        <el-button @click="parentDialogVisible = false" size="small">取 消</el-button>
                        <el-button type="primary" @click="parentDialogVisible = false" size="small">确 定</el-button>
                    </span>
                </el-dialog>

                <!-- 分配角色弹框 -->
                <el-dialog class="self_dialog" :title="roleDialog.dialogTitle" :visible.sync="roleDialog.visible" width="45%" top="5%">
                    <el-radio-group v-model="userForm.roleId">
                        <el-radio :label="item.id" v-for="item in rolesData" :key="item.id">{{item.name}}</el-radio>
                    </el-radio-group>
                    <span slot="footer" class="dialog-footer">
                        <el-button @click="roleDialog.visible = false" size="small">取 消</el-button>
                        <el-button type="primary" @click="saveUserRoleFun()" :loading="loading.status" size="small">{{loading.status ? loading.SubText : loading.BtnText}}</el-button>
                    </span>
                </el-dialog>

                <!-- 导出信息弹框 -->
                <el-dialog class="self_dialog" title="导出" :visible.sync="exportDialogVisible" width="45%" top="5%">
                    <el-checkbox :indeterminate="isIndeterminate" v-model="checkAllColumns" @change="handleCheckAllChange">全选</el-checkbox>
                    <div style="margin: 15px 0;"></div>
                    <el-checkbox-group v-model="checkedColumns" @change="handleCheckedCitiesChange">
                        <el-checkbox v-for="item in userExportData" :label="item.value" :key="item.value">{{item.name}}</el-checkbox>
                    </el-checkbox-group>
                    <div style="margin: 15px 0;"></div>
                    <div class="export-tip">说明: 导出文件相当耗时，请耐心等待，如果中途导出失败，请刷新浏览器，重新操作</div>
                    <span slot="footer" class="dialog-footer">
                        <el-button @click="exportDialogVisible = false" size="small">取 消</el-button>
                        <el-button type="primary" @click="handleExport()" :loading="loading.status" size="small">{{loading.status ? loading.SubText : loading.BtnText}}</el-button>
                    </span>
                </el-dialog>
            </el-col>
        </el-row>
    </div>
</template>

<script>
export default {
    data() {
        return {
            // 弹出层大小
            size: '25%',
            // 是否显示树状弹出层
            parentDialogVisible: false,
            // 导出列选择
            exportDialogVisible: false,
            // 默认是否全选
            checkAllColumns: false,
            // 绑定默认选中
            checkedColumns: [],
            // 数据源
            userExportData: [
                {name:'账号',value:'username'},
                {name: '用户名',value: 'accountName'},
                {name:'邮箱',value:'email'},
                {name:'部门名称',value:'deptName'},
                {name:'管理员标识',value:'isAdmin'},
                {name:'创建时间',value:'createTime'}
            ],
            // 设置indeterminate状态，只负责样式控制
            isIndeterminate: true,
            // 表格数据
            tableData: [],
            // 表格高度
            tableHeight: 0,
            // 查询参数
            searchForm: {
                accountName: null,
                deptId: null,
                isEnabled: null
            },
            // 表单参数
            userForm: {
                id: null,
                deptId: null,
                deptName: null,
                username: null,
                password: null,
                accountName: null,
                email: null,
                roleId: null,
                userRoleId: null,
                enabled: true,
				newPassword: null,
				oldPassword: "0"
            },
            // 角色数据
            rolesData: [],
            // 分页数据
            total: 0,
            pageNum: 1,
            pageSize: 8,
            // 弹出层
            dialog:{
                flag: 0,
                dialogTitle: "",
                visible: false,
                direction: 'rtl'
            },
			dialogPWD:{
				flag: 0,
				dialogTitle: "",
				visible: false,
				direction: 'rtl'
			},
            // 角色弹出层
            roleDialog:{
                flag: 1,
                dialogTitle: "",
                visible: false,
                direction: 'rtl'
            },
            loading: {
                status: false,
                BtnText: '确 定',
                SubText: '提交中...'
            },
            // 所有部门数据
            treeData: [],
            // 树形控件的属性绑定对象
            treeProps: {
                children: 'children',
                label: 'name'
            },
            // 默认选中的节点id值
            defKeys: [],
            // 树节点关键字过滤
            filterText: '',
            // 表单校验
            rules: {
                deptName: [{required: true, trigger: "change",  message: "请选择所属部门"}],
                username: [{required: true, trigger: "change",  message: "请输入用户账号"}],
                password: [{required: true, trigger: "change",  message: "请输入登录密码"}],
                accountName: [{required: true, trigger: "change",  message: "请输入用户姓名"}],
                email: [{required: true, trigger: "change",  message: "请输入邮箱"}],
                roleId: [{required: true, trigger: "change",  message: "请选择角色"}]
            }
        };
    },
    mounted() {
        this.$nextTick(() => {
            this.tableHeight = window.innerHeight - 250;
        });
    },
    created() {
        this.getTreeData()
        this.getDataList()
        this.getRoleList()
    },
    watch: {
        // 监听树节点关键字过滤操作
        filterText(val) {
            this.$refs.searchTreeRef.filter(val);
        }
    },
    methods: {
        handleClose(done) {
            this.resetForm()
            done()
        },
        // 导出列全选
        handleCheckAllChange(val) {
            // 当全选被选中的时候，循环遍历源数据，把数据的每一项加入到默认选中的数组去
            this.userExportData.forEach(item=>{
                this.checkedColumns.push(item.value)
            })
            this.checkedColumns = val ? this.checkedColumns : [];
            this.isIndeterminate = false;
        },
        // 导出列选中
        handleCheckedCitiesChange(value) {
            let checkedCount = value.length;
            this.checkAllColumns = checkedCount === this.userExportData.length;
            this.isIndeterminate = checkedCount > 0 && checkedCount < this.userExportData.length;
        },
        // 树节点关键字过滤
        filterNode(value, data) {
            if (!value) return true;
            return data.name.indexOf(value) !== -1;
        },
        // 分配角色按钮操作
        assignRole(row) {
            this.roleDialog.visible = true
            this.roleDialog.dialogTitle = '【' + row.username + '】分配角色'
            this.getById(row.id)
        },
        // 保存角色分配
        saveUserRoleFun() {
            this.loading.status = true
            this.$api.user.saveOrUpdate(this.userForm,this.roleDialog.flag).then(res => {
                if (res.data.code === 2000) {
                    this.$message.success(res.data.msg)
                    this.getDataList()
                    this.roleDialog.visible = false
                    this.loading.status = false
                }else{
                    this.$message.error(res.data.msg)
                    this.loading.status = false
                    return false
                }
            })
        },
        // 获取全部角色
        getRoleList() {
            this.$api.role.findAll().then(res => {
                if(res.data.code === 2000){
                    this.rolesData = res.data.data
                }
            })
        },
        // 展示部门对话框
        showAssignDialog(deptId) {
            this.getTreeData()
            // 默认选中根节点
            this.defKeys = [deptId]
            this.parentDialogVisible = true
        },
        handleSizeChange(val) {
            this.pageSize = val
            this.getDataList()
        },
        handleCurrentChange(val) {
            this.pageNum = val
            this.getDataList()
        },
        // 获取表格数据
        getDataList() {
            this.$api.user.list({
                current: this.pageNum,
                size: this.pageSize,
                deptId: this.searchForm.deptId,
                accountName: this.searchForm.accountName,
                isEnabled: this.searchForm.isEnabled
            }).then(res => {
                if(res.data.code === 2000){
                    this.tableData = res.data.data.records
                    this.total = res.data.data.total
                }
            })
        },
        // 获取所有部门信息
        getTreeData() {
            this.$api.dept.listTree(2).then(res => {
                if(res.data.code === 2000){
                    this.treeData = res.data.data
                }
            })
        },
        // 节点单击事件
        searchHandleNodeClick(data) {
            if(data.pid !== '0') {
                this.searchForm.deptId = data.id
            }else {
                this.searchForm.deptId = null
            }
            this.getDataList()
        },
        // 树组件单选实现
        handleNodeClick(data, checked) {
            if(checked === true) {
                this.userForm.deptName = data.name
                this.userForm.deptId = data.id
                this.$refs.treeRef.setCheckedKeys([data.id]);
            } else {
                if (this.userForm.deptId === data.id) {
                    this.$refs.treeRef.setCheckedKeys([data.id]);
                }
            }
        },
        // 新增按钮操作
        openAdd() {
            // 部门节点选中清空
            this.userForm.deptId = null
            this.dialog.flag = 0
            this.resetForm("userForm")
            this.dialog.dialogTitle = "新增用户"
            this.dialog.visible = true
        },
        // 更新按钮操作
        openUpdate(row) {
            this.dialog.flag = 1
            this.resetForm("userForm")
            this.dialog.dialogTitle = "编辑用户"
            this.dialog.visible = true
            this.getById(row.id)
        },
		//修改密码按钮
		openUpdatePWD(row) {
			this.userForm.id = row.id;
			this.userForm.newPassword = "";
		    this.dialogPWD.flag = 1
		    //this.resetForm("userFormPWD")
		    this.dialogPWD.dialogTitle = "编辑用户"
		    this.dialogPWD.visible = true
		    //this.getById(row.id)
		},
        // 提交数据操作
        submitFun() {
            this.$refs.userForm.validate(valid => {
                if(valid){
                    this.loading.status = true
                    this.$api.user.saveOrUpdate(this.userForm,this.dialog.flag).then(res => {
                        if (res.data.code === 2000) {
                            this.$message.success(res.data.msg)
                            this.getDataList()
                            this.dialog.visible = false
                            this.loading.status = false
                        }else{
                            this.$message.error(res.data.msg)
                            this.loading.status = false
                            return false
                        }
                    })
                }
            })
        },
		// 提交修改密码数据
		submitFunPWD() {
		    this.$confirm("确定要提交密码？", "系统提示", {
		        confirmButtonText: "确定",
		        cancelButtonText: "取消",
		        type: 'error'
		    }).then(() =>{
		        //确定执行
				this.$api.user.updatePwdByAdmin(this.userForm,this.dialog.flag)
					.then(res => {
						if (res.data.code === 2000) {
							this.$message.success(res.data.msg)
							this.dialogPWD.visible = false
							this.loading.status = false
							this.userForm.id = "";
						}else{
							this.$message.error(res.data.msg)
							this.loading.status = false
							this.userForm.id = "";
							return false
						}
					});
		    }).catch(() => {
		        this.$message.info("取消修改");
				this.userForm.id = "";
		    });
		},
		
        // 删除按钮操作
        deleteFun(row) {
            this.$confirm("确定删除当前用户吗？", "系统提示", {
                confirmButtonText: "确定",
                cancelButtonText: "取消",
                type: 'error'
            }).then(() =>{
                this.$api.user.remove(row.id).then(res => {
                    if(res.data.code === 2000){
                        this.$message.success(res.data.msg)
                        this.getDataList()
                    }else {
                        this.$message.error(res.data.msg)
                    }
                })
            }).catch(() => {
                this.$message.info("取消删除")
            });
        },
        // 根据id获取信息
        getById(id) {
            this.$api.user.getById(id).then(res => {
                if (res.data.code === 2000) {
                    this.userForm = res.data.data;
                }
            })
        },
        // 更新用户状态
        handleStatusChange(row) {
            let text = row.enabled === true ? "启用" : "停用";
            this.$confirm('确认要"' + text + '""' + row.accountName + '"用户吗？', "系统提示", {
                confirmButtonText: "确定",
                cancelButtonText: "取消",
                type: 'warning'
            }).then(() =>{
                this.$api.user.updateUserStatus(row.id,row.enabled).then(res => {
                    if(res.data.code === 2000){
                        this.$message.success(text + "成功")
                        this.getDataList()
                    }else {
                        this.$message.error(res.data.msg)
                    }
                })
            }).catch(() => {
                this.$message.info("取消更新")
            });
        },
        // 导入用户数据
        handleImport() {
            this.$api.user.importUser().then(res => {
                if(res.data.code === 2000){
                    this.$message.success("导入成功")
                }else {
                    this.$message.error(res.data.msg)
                }
            })
        },
        // 导出弹框
        openExport() {
            this.exportDialogVisible = true
        },
        // 导出用户数据
        handleExport() {
            if(this.checkedColumns.length === 0) {
                this.$message.warning("请筛选要导出的列")
                return false
            }
            this.$api.user.exportUser(this.checkedColumns).then(res => {
                // 获取文件名
                const disposition = res.headers['content-disposition'];
                let fileName = disposition.substring(disposition.indexOf('filename=') + 9, disposition.length);
                const blob = new Blob([res.data],{type: "application/vnd.ms-excel"});
                // 创建一个超链接
                const eLink = document.createElement("a");
                eLink.download = decodeURI(fileName);
                eLink.style.display = "none";
                eLink.href = URL.createObjectURL(blob);
                document.body.appendChild(eLink);
                eLink.click();
                // 释放URL对象
                URL.revokeObjectURL(eLink.href);
                document.body.removeChild(eLink);
            })
        },
        // 清空表单
        resetForm(formName) {
            this.userForm.password = null
            if (this.$refs[formName]) {
                this.$refs[formName].resetFields();
            }
        },
		openClearCache(){
			this.$confirm('确认要清除登录权限缓存吗？', "系统提示", {confirmButtonText: "确定",cancelButtonText: "取消",type: 'warning'}).then(() =>{
				this.$api.menu.clearCache().then(res => {
					if(res.data.code === 2000){
						this.$message.success("清除成功")
					}else {
						this.$message.error(res.data.msg)
					}
				})
			}).catch(() => {
				this.$message.info("取消清除")
			});
		},
    }
};
</script>

<style lang="less" scoped>
.el-search-item {
    margin-bottom: 0;
}
.el-card/deep/.el-card__body {
    padding: 0 10px 20px 10px !important;
}
.el-card/deep/.el-card__header {
    border-bottom: none !important;
}
.tree-dept{
    overflow-y: auto;
    overflow-x: hidden;
    max-height: 543px;
    min-height: 543px;
}
.tree-dept::-webkit-scrollbar {
    /*整体样式*/
    width: 5px;
    height: 2px;
}
.tree-dept::-webkit-scrollbar-track {
    /*轨道*/
    box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
    background: #ededed;
    border-radius: 10px;
}
.tree-dept::-webkit-scrollbar-thumb {
    /*滚动条小方块*/
    border-radius: 5px;
    background-color: #c0c4cc;
    background-image: -webkit-linear-gradient(
        45deg,
        rgba(255, 255, 255, 0.2) 25%,
        transparent 25%,
        transparent 50%,
        rgba(255, 255, 255, 0.2) 50%,
        rgba(255, 255, 255, 0.2) 75%,
        transparent 75%,
        transparent
    );
}

.is-circle{
    width: 8px;
    height: 8px;
    background-color: #67c23a;
    border-radius: 50%;
    display: inline-block;
    margin-right: 5px;
}
.not-circle{
    width: 8px;
    height: 8px;
    background-color: #f56c6c;
    border-radius: 50%;
    display: inline-block;
    margin-right: 5px;
}
.export-tip {
    color: #909399;
}
</style>
